from django.shortcuts import render

# Create your views here.
from rest_framework import status
from rest_framework.response import Response
from rest_framework.utils import json
from rest_framework.views import APIView
from rest_framework_jwt.settings import api_settings

from oauth.models import OAuthQQUser, OAuthSinaUser
from oauth.serializers import OAuthQQUserSerializers, OAuthWeiBoUserSerializer
from users.models import User
from utils.weibo import OAuthWeibo

"""
实现第三方登录的步骤:
第一步:先到响应的开发者平台中,申请成为开发者
        个人开发者
        企业开发者
第二部:成为开发者之后,申请应用
        app id
        app secret
第三步:按照文档开发
    1.添加图标
    2.添加图标的按钮点击
    3.点击图标的时候转到一个页面
    4.这个页面获取用户同意之后获取一个code
    5.通过code换取token
    6.通过token获取openid
    
    openid是此网站上唯一对应用户身份的标识，
    网站可将此ID进行存储便于用户下次登录时辨识其身份，
    或将其与用户在网站上的原有账号进行绑定。 
    openid要和已有的帐号进行一个1:1的关系
    
 
"""

"""
我们后端 需要拼接跳转的url,拼接成功之后,返回给前端

看接口文档
"""

from QQLoginTool.QQtool import OAuthQQ
from mall import settings

class OAuthWeiBoUrlAPIView(APIView):

    def get(self, requset):
        data = requset.query_params.get("next", "/")
        # state = 'test'
        state = "/"
        if not data:
            from rest_framework import status
            return Response(status=status.HTTP_404_NOT_FOUND)
        wei_bo = OAuthWeibo(client_id=settings.CLIENT_ID, client_secret=settings.CLIENT_SECRET, redirect_uri=settings.REDIRECT_URI, state=state)
        auth_url = wei_bo.get_weibo_url()
        return Response({
            'auth_url': auth_url
        })


class OAuthWeiBoAPIView(APIView):

    def get(self, request):
        code = request.query_params.get('code')
        if code is None:
            return Response(status=status.HTTP_400_BAD_REQUEST)

        wei_bo = OAuthWeibo(client_id=settings.CLIENT_ID, client_secret=settings.CLIENT_SECRET, redirect_uri=settings.REDIRECT_URI)
        access_token = wei_bo.get_access_token(code) #access_token
        try:
            wei_bo_user = OAuthSinaUser.objects.get(access_token=access_token)
        except OAuthSinaUser.DoesNotExist:
            return Response(data={
                'access_token': access_token
            })
        else:
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            payload = jwt_payload_handler(wei_bo_user.user)
            token = jwt_encode_handler(payload)
            return Response({
                'user_id': wei_bo_user.user.id,
                'username': wei_bo_user.user.username,
                'token': token
            })

    def post(self, request):

        data = request.data
        p = data.keys()
        l = list(p)
        f = l[0]
        o = json.loads(f)
        serializer = OAuthWeiBoUserSerializer(data=o)
        serializer.is_valid(raise_exception=True)
        weibo_user = serializer.save()
        user_id = weibo_user.user_id

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(weibo_user.user)
        token = jwt_encode_handler(payload)

        return Response({
            'user_id': weibo_user.user.id,
            'username': weibo_user.user.username,
            'token': token
        })




class OauthQQUrlAPIView(APIView):
    def get(self,request):
        # state = 'test'
        state = 'user_center_info.html'
        # auth_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=101474184&redirect_uri=http://www.meiduo.site:8080/oauth_callback.html&state=123"
        qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI, state=state)
        auth_url = qq.get_qq_url()
        return Response({"auth_url":auth_url})

"""
当用户同意登录之后,腾讯的服务器会生成一个code,这个code在回调的url中

一,大体的步骤
    # 1.接受code
    # 2.通过code换取token(是我们通过请求向腾讯的服务器换)
    # 3.通过token换取openid(openid是此网站上唯一对应用户身份的标识)
二,确定请求方式和路由
    GET /oauth/qq/users/?code=xxx

"""

class OAuthQQUserAPIView(APIView):

    def get(self,request):
        # 1.接受code
        code = request.query_params.get('code')
        if code is None:
            from rest_framework import status
            return Response(status=status.HTTP_400_BAD_REQUEST)

        # 2.通过code换取token(是我们通过请求向腾讯的服务器换)
        qq = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET, redirect_uri=settings.QQ_REDIRECT_URI)
        token = qq.get_access_token(code)
        # 3.通过token换取openid(openid是此网站上唯一对应用户身份的标识)
        openid = qq.get_open_id(token)
        # 4.我们需要根据openid进行判断(根据openid进行查询)
        # 如果用户绑定过,则直接登录
        # 如果用户没有绑定过,则进行绑定
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 说明不存在,就应该绑定
            # 1. openid属于敏感数据
            # 2. 绑定的时候应该有一个时效
            #  JWS可以实现以上的功能
            from oauth.utils import generic_openid_token
            openid_token = generic_openid_token(openid)

            return Response({'access_token': openid_token})

        else:
            from rest_framework_jwt.settings import api_settings
            # 说明存在,存在应该登录
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            user = qquser.user
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return Response({
                'token': token,
                'user_id': user.id,
                'username': user.username
            })
    def post(self,request):
        # 大体思路:
        # 1.接受参数 mobile,password,sms_code,access_token
        data = request.data
        serializer = OAuthQQUserSerializers(data=data)
        serializer.is_valid(raise_exception=True)
        qquser=serializer.save()
        # 生成JWT token，并响应
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
        payload = jwt_payload_handler(qquser.user)
        token = jwt_encode_handler(payload)
        # 2.验证数据
        #     access_tooken
        #     sms_code
        #     根据手机号判断用户是否注册
        #
        # 3.保存数据
        # 4.返回响应
        #
        # 确定请求方式和路由
        return Response({
            'user_id':qquser.user.id,
            'username':qquser.user.username,
            'token':token
        })

"""
当用户点击头像授权统一的时候,后端会将生成的code换取成最终的openid,然后返回给前端
当用户点击保存的时候,需要让前端将手机号,密码.短信验证码,以及加密之后的openid提交给后端
后端:
    # 大体思路:
    # 1.接受参数 mobile,password,sms_code,access_token
    # 2.验证数据
    #     access_tooken
    #     sms_code
    #     根据手机号判断用户是否注册
    #     
    # 3.保存数据
    # 4.返回响应
    # 
    # 确定请求方式和路由
    post
"""

# from itsdangerous import  JSONWebSignatureSerializer  # 没有时间 不用
# # 1.导入
# from  itsdangerous import TimedJSONWebSignatureSerializer as Serializer
# from mall import settings
# # secret_key, expires_in=None
# # secret_key  密钥一般(习惯)使用settings中的secret_key
# # expires_in  秒数,过期时间
# serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=60*60)
# # 组装字典数据
# data = {
#     'openid':'123'
# }
# # 4.对数据进行加密(签名)
# token = serializer.dumps(data)
# token.decode()
#
#
# #######################333验证数据#####################
# serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=60*60)
# serializer.loads(token)
#
# serializer = Serializer(secret_key=settings.SECRET_KEY,expires_in=1000)
# data = {
#     'openid':'123'
# }
# # eyJpYXQiOjE1NTQwODQyNTEsImFsZyI6IkhTMjU2IiwiZXhwIjoxNTU0MDg1MjUxfQ.eyJvcGVuaWQiOiIxMjMifQ.70TgpacWjk9QvfjkbsGBq1kCjmSwCdVZelsQeZTxLMg
# token = serializer.dumps(data)
# serializer.loads(token)